Managing LXC hosts with ansible and a jump host
I wanted to be able to create a LXC guests using ansible and then manage said guests without having them public.
Since my last attempt two years ago things have changed
1 Create an LXC guest using ansible
this ended up beeing quite easy with the help of the lxc_container module.
It just needs the lxc package and python2-lxc.
1.1 python2-lxc and ubuntu 14.04
Sadly python2-lxc is not packaged for ubuntu 14.04, luckily pip made it easy to install
- apt: name={{item}} with_items: - python-pip - git - build-essential - python-dev - lxc-dev pip: name=git+https://github.com/lxc/python2-lxc.git#egg=python2-lxc
1.2 Create the container !
Pretty easy, the documentation has a bunch of examples. I added the `container_command` so python would be installed before beeing contacted by ansible.
We could also configure the authorized_keys in there too.
- name: Prepare lxc-www1 container lxc_container: name: lxc-www1 state: started template_options: --release trusty container_config: - "lxc.network.type=veth" - "lxc.aa_profile=unconfined" container_command: | apt-get install -y python register: www1_conf
The lxc_container's name can't be changed without popping a new container, also chose wisely … it will be repeated and reused as the playbook hostname and in ssh_config.
Now what's next ? How will the next play know this host has been created ?
2 add_host !
3 The ssh connection
3.1 The Play
We reuse the name we used for the container name, in our example `lxc-www1`.
- hosts: lxc-www1 tasks: - debug: var="hostvars['lxc-www1']"
3.2 The trick
Using a jump host is not new, we configure a ProxyCommand in our ~/.ssh/config that will forward our ssh connection to another host.
The issue, was how to connect to an LXC host we don't have the IP. Actually we have the IP by default it's in the 10.0.3.0/24. But since I also have LXC guests on my laptop, I didn't want to catch those ssh connections by setting `Host 10.0.3.*`. Instead I chose `lxc-*`.
Next, was how to forward the connection to the lxc guest, since I still don't have it's IP and the hostname doesn't resolve ?
lxc-attach can attach and run commands on the host, using `nc` we can now forward what the ssh client is sending to the ssh server on the guest.
Host my-lxc-host Hostname X.X.X.X Host lxc-* ProxyCommand ssh my-lxc-host lxc-attach -n %h nc localhost 22
%h will use the hostname we are trying to contact, which is actually our lxc container name
4 Even better
It might be possible to tell ansible to use another ssh_config and keep everything along the rest of the configurations/playbooks.
If `add_host` could configure `ssh_args` it would be a simple matter of doing something like
- add_host: name=blahblah ssh_args="-o ProxyCommand ssh {{inventory_name}} -W {{www1_conf.lxc_container.ipv4[0]}}"